// SPDX-FileCopyrightText: Adam Evyčędo
//
// SPDX-License-Identifier: GPL-3.0-or-later

package xyz.apiote.bimba.czwek.repo

import android.content.Context
import android.location.Location
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import xyz.apiote.bimba.czwek.api.PositionV1
import xyz.apiote.bimba.czwek.data.traffic.Place

@Parcelize
data class Position(val positionLatitude: Double, val positionLongitude: Double) : Parcelable, Place {
	init {
		if (positionLatitude > 90 || positionLatitude < -90 || positionLongitude > 180 || positionLongitude < -180) {
			throw IllegalArgumentException("$positionLatitude must be [-90, 90], $positionLongitude must be [-180, 180]")
		}
	}

	constructor(p: PositionV1) : this(p.latitude, p.longitude)
	constructor(l: Location) : this(l.latitude, l.longitude)

	fun isInside(bl: Position, tr: Position): Boolean {
		return positionLatitude >= bl.positionLatitude &&
				positionLatitude <= tr.positionLatitude &&
				positionLongitude >= bl.positionLongitude &&
				positionLongitude <= tr.positionLongitude

		// TODO support near lon 180
	}

	fun isZero(): Boolean {
		return positionLatitude == 0.0 && positionLongitude == 0.0
	}

	fun distanceTo(other: Position): Float {
		return Location(null).apply {
			latitude = this@Position.positionLatitude
			longitude = this@Position.positionLongitude
		}.distanceTo(Location(null).apply {
			latitude = other.positionLatitude
			longitude = other.positionLongitude
		})
	}

	override fun toString(): String {
		return "$positionLatitude,$positionLongitude"
	}

	override fun getName(): String = ""

	override fun getDescription(
		context: Context,
		decoration: Stop.LineDecoration
	): String = ""

	override fun getLatitude(): Double = positionLatitude

	override fun getLongitude(): Double = positionLongitude

	override fun getJourneyID() = "${positionLatitude},${positionLongitude},0"

	override fun getShortName() = "%.2f, %.2f".format(
			positionLatitude,
			positionLongitude
		)

	override fun getPosition(): Position = this
	fun toLocation(): Location {
		return Location(null).apply {
			latitude = positionLatitude
			longitude = positionLongitude
		}
	}

	companion object {
		fun comparator(centre: Position) =
			Comparator<Position> { o1, o2 ->
				if (o1 == null || o2 == null) {
					throw NullPointerException()
				}

				o1.distanceTo(centre).compareTo(o2.distanceTo(centre))
			}
	}
}
